package cn.whale.service;

import cn.whale.pojo.entity.SubtitleSrt;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * 有关字幕文件的处理
 */
public class SubtitleService {
    /**
     * 指定目录下的所有双语ass字幕文件转化为srt字幕文件且上中下英
     *
     * @param path 目标目录地址
     */
    public void doubleSubtitleList(String path) {
        Path directory = Paths.get(path);
        try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(directory)) {
            for (Path p : directoryStream) {
                doubleSubtitle(path + p.getFileName().toString());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 指定双语ass字幕文件转化为srt字幕文件且上中下英
     *
     * @param filePath 文件地址
     */
    public void doubleSubtitle(String filePath) {
        List<String> lines = readFile(filePath);
        List<SubtitleSrt> srtLines = assToSrt(lines);
        filePath = filePath.split(".ass")[0] + "英简.srt";
        writeFile(filePath, srtLines);
    }

    /**
     * 将处理好的字幕文件写入目标文件
     *
     * @param filePath 目标文件地址
     * @param srtLines 字幕数据
     */
    private void writeFile(String filePath, List<SubtitleSrt> srtLines) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            int i = 1;
            for (SubtitleSrt subtitleSrt : srtLines) {
                writer.write(i + "\n");
                i++;
                writer.write(subtitleSrt.getTime() + "\n");
                writer.write(subtitleSrt.getEnglish() + "\n");
                writer.write(subtitleSrt.getChinese() + "\n");
                writer.newLine();
            }
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将ass字幕数据转化为srt字幕数据
     *
     * @param lines ass字幕数据
     * @return srt字幕数据
     */
    private List<SubtitleSrt> assToSrt(List<String> lines) {
        List<SubtitleSrt> subtitles = new ArrayList<>();
        for (String line : lines) {
            String[] parts = line.split(",");
            SubtitleSrt subtitleSrt = new SubtitleSrt();
            subtitleSrt.setTime(timeChange(parts[1]) + " --> " + timeChange(parts[2]));
            SubtitleConcat(subtitleSrt, parts);
            subtitles.add(subtitleSrt);
        }
        return subtitles;
    }

    /**
     * ass字幕内容位置调整
     *
     * @param subtitleSrt srt单行字幕数据
     * @param parts       ass但行字幕数据
     */
    private void SubtitleConcat(SubtitleSrt subtitleSrt, String[] parts) {
        StringBuilder subTitle = new StringBuilder();
        for (int i = 9; i < parts.length; i++) {
            if (i == 9) {
                subTitle.append(parts[i]);
            } else {
                subTitle.append(",").append(parts[i]);
            }
        }
        String[] split = subTitle.toString().replaceAll("\\{.*?\\}", "")
                .split("\\\\N");
        if (split.length == 2) {
            subtitleSrt.setEnglish(split[1]);
            subtitleSrt.setChinese(split[0]);
        } else {
            subtitleSrt.setEnglish("");
            for (String s : split) {
                subtitleSrt.setEnglish(subtitleSrt.getEnglish() + "\\N");
            }
        }
    }

    /**
     * ass字幕时间转换为srt字幕时间
     *
     * @param time ass字幕自己
     * @return 返回srt字幕时间
     */
    public String timeChange(String time) {
        String[] strings = time.split("\\.");
        time = strings[0] + "," + strings[1] + "0";
        return time;
    }

    /**
     * 读取ass字幕文件内容
     *
     * @param filePath ass字幕文件地址
     * @return 返回去掉文字样式每行字幕集合
     */
    private List<String> readFile(String filePath) {
        List<String> linesNew = new ArrayList<>();
        try {
            List<String> lines = Files.readAllLines(Paths.get(filePath));
            for (String line : lines) {
                if (line.contains("Dialogue")) {
                    linesNew.add(line);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return linesNew;
    }
}
